package ink.xiaobaibai.controller.buy;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import ink.xiaobaibai.annotation.InsidePublicResources;
import ink.xiaobaibai.autoConfig.roleResources.ResourcesRoleMapping;
import ink.xiaobaibai.common.BuyBindOne;
import ink.xiaobaibai.common.MyRole;
import ink.xiaobaibai.common.RoleEvents;
import ink.xiaobaibai.entity.*;
import ink.xiaobaibai.enumOxy.BuyOrderStatus;
import ink.xiaobaibai.multipleClick.ForbidMultipleClick;
import ink.xiaobaibai.response.ResponseFormat;
import ink.xiaobaibai.service.*;
import ink.xiaobaibai.serviceOxy.ISmsService;
import ink.xiaobaibai.units.MySecurity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @description: 购买业务流程控制层
 * @author: 小白白
 * @create: 2021-06-13
 **/

@RestController
@RequestMapping("/buy/procedure")
@Api(tags = "购买业务流程接口")
@CrossOrigin
@InsidePublicResources
public class BuyProcedureController {

    @Autowired
    private IBuyOrderService buyOrderService;

    @Autowired
    private IBuyOzoneDeviceService buyOzoneDeviceService;

    @Autowired
    private IBuyOxygenDeviceService buyOxygenDeviceService;

    @Autowired
    private IAdminUserService adminUserService;

    @Autowired
    private ILogisticsBuyService logisticsBuyService;

    @Autowired
    private ISmsService smsService;

    /**
     * 查看自己的流程待处理订单
     */
    @GetMapping("/list")
    @ApiOperation("查看自己的流程待处理订单")
    public ResponseFormat list() {
        Integer userId = MySecurity.getUserId();
        String role = MySecurity.getRole();
        QueryWrapper<BuyOrder> q1 = new QueryWrapper<>();
        RoleEvents roleEvents = new RoleEvents(role);
        roleEvents
                .distributor(() -> {
                    q1.eq("admin_user_id", userId);
                    q1.notIn("status", BuyOrderStatus.complete.getStatus());
                })
                .agent(() -> {
                    q1.eq("admin_dep_id", this.adminUserService.getDepId(userId));
                    q1.eq("status", BuyOrderStatus.agent.getStatus());
                })
                .admin(() -> {
                    q1.eq("status", BuyOrderStatus.admin.getStatus());
                })
                .execute();
        q1.orderByDesc("create_time");
        List<BuyOrder> list = this.buyOrderService.list(q1);
        return ResponseFormat.success(list);
    }

    /**
     * 一:业务员绑定机器
     */
    @PostMapping("/bindOne")
    @ApiOperation("为订单绑定机器+备注+物流订单号")
    @ForbidMultipleClick(key = "#buyBindOne.orderId")
    public ResponseFormat bindOne(@RequestBody @Validated BuyBindOne buyBindOne) {
        BuyOrder order = this.buyOrderService.getById(buyBindOne.getOrderId());
        BuyOzoneDevice ozoneDevice = this.buyOzoneDeviceService.getById(buyBindOne.getDeviceId());
        ResponseFormat responseFormat = this.validDevice(order, ozoneDevice);
        if (responseFormat.getCode() == 1) {
            return responseFormat;
        }
        //订单
        order.setDeviceId(buyBindOne.getDeviceId());
        order.setDeviceCode(ozoneDevice.getDeviceCode());
        String role = MySecurity.getRole();
        if (MySecurity.isPower(MyRole.POWER_BUY)) {
            order.setStatus(BuyOrderStatus.complete.getStatus());
        } else if (role.equals(MyRole.AGENT)) {
            order.setStatus(BuyOrderStatus.admin.getStatus());
            this.smsService.oaSms(1, "购买");
        } else {
            AdminUser adminUser = this.adminUserService.getAgentIdByDepId(this.adminUserService.getDepId(MySecurity.getUserId()));
            this.smsService.oaSms(adminUser.getId(), "购买");
            order.setStatus(BuyOrderStatus.agent.getStatus());
        }
        order.setRemarks(buyBindOne.getRemarks());
        this.buyOrderService.updateById(order);
        UpdateWrapper<LogisticsBuy> u1 = new UpdateWrapper<>();
        u1.set("number", buyBindOne.getLogisticsNumber());
        u1.eq("id", order.getLogisticsBuyId());
        this.logisticsBuyService.update(u1);
        return ResponseFormat.success();
    }

    /**
     * 一:业务员修改绑定机器
     */
    @PostMapping("/bindOne-update")
    @ApiOperation("为订单修改机器+备注+物流订单号+姓名+电话+地址")
    @ForbidMultipleClick(key = "#buyBindOne.orderId")
    public ResponseFormat updateBindOne(@RequestBody @Validated BuyBindOne buyBindOne) {
        BuyOrder order = this.buyOrderService.getById(buyBindOne.getOrderId());
        BuyOzoneDevice ozoneDevice = this.buyOzoneDeviceService.getById(buyBindOne.getDeviceId());
        if (ozoneDevice.getId().equals(buyBindOne.getDeviceId())) {
            order.setRemarks(buyBindOne.getRemarks());
            this.buyOrderService.updateById(order);
            return ResponseFormat.fail("机器未改变,已改变备注");
        }
        ResponseFormat responseFormat = this.validDevice(order, ozoneDevice);
        if (responseFormat.getCode() == 1) {
            return responseFormat;
        }
        //old臭氧机器改回去
        Integer deviceId = order.getDeviceId();
        UpdateWrapper<BuyOzoneDevice> u1 = new UpdateWrapper<>();
        u1.set("client_user_id", null);
        u1.eq("id", deviceId);
        this.buyOzoneDeviceService.update(u1);
        //old氧气机是否还被引用着?
        Integer oxygenId = ozoneDevice.getOxygenId();
        QueryWrapper<BuyOzoneDevice> q1 = new QueryWrapper<>();
        q1.eq("oxygen_id", oxygenId);
        q1.last("limit 1");
        if (this.buyOzoneDeviceService.count(q1) == 0) {
            UpdateWrapper<BuyOxygenDevice> u2 = new UpdateWrapper<>();
            u1.set("client_user_id", null);
            u1.eq("id", oxygenId);
            this.buyOxygenDeviceService.update(u2);
        }
        //订单
        order.setDeviceId(buyBindOne.getDeviceId());
        order.setDeviceCode(ozoneDevice.getDeviceCode());
        order.setRemarks(buyBindOne.getRemarks());
        this.buyOrderService.updateById(order);

        UpdateWrapper<LogisticsBuy> u3 = new UpdateWrapper<>();
        u3.set("name", buyBindOne.getName());
        u3.set("phone", buyBindOne.getPhone());
        u3.set("address", buyBindOne.getAddress());
        u3.eq("id", order.getLogisticsBuyId());
        this.logisticsBuyService.update(u3);

        return ResponseFormat.success();
    }

    /**
     * 经理确认
     */
    @PostMapping("/bindTwo")
    @ApiOperation("经理确认自己部门的购买订单")
    @ForbidMultipleClick(key = "#orderId")
    public ResponseFormat bindTwo(@RequestBody String orderId) {
        Integer userId = MySecurity.getUserId();
        String role = MySecurity.getRole();
        if (!role.equals(MyRole.AGENT)) {
            return ResponseFormat.fail("非经理不可操作");
        }
        Integer depId = this.adminUserService.getDepId(userId);
        BuyOrder order = this.buyOrderService.getById(orderId);
        if (!order.getAdminDepId().equals(depId)) {
            return ResponseFormat.fail("不可操作其他部门订单");
        }
        if (order.getStatus().equals(BuyOrderStatus.complete.getStatus()) || order.getStatus().equals(BuyOrderStatus.refunded.getStatus())) {
            return ResponseFormat.fail("操作失败,当前订单状态:" + order.getStatus());
        }
        if (!order.getStatus().equals(BuyOrderStatus.agent.getStatus())) {
            return ResponseFormat.fail("操作失败,当前订单状态:" + order.getStatus() + ",未到当前流程");
        }
        order.setStatus(BuyOrderStatus.admin.getStatus());
        this.buyOrderService.updateById(order);
        return ResponseFormat.success();
    }

    /**
     * 管理员确认 机器可用状态
     */
    @PostMapping("/bindThree")
    @ApiOperation("管理员确认购买订单")
    @ResourcesRoleMapping(resourceName = "管理获取购买订单审核集合", includeRoleNames = {MyRole.ADMIN, MyRole.POWER_BUY})
    @ForbidMultipleClick(key = "#orderId")
    public ResponseFormat bindThree(@RequestBody String orderId) {
        BuyOrder order = this.buyOrderService.getById(orderId);
        if (order == null) {
            return ResponseFormat.fail("无此订单");
        }
        if (order.getStatus().equals(BuyOrderStatus.complete.getStatus()) || order.getStatus().equals(BuyOrderStatus.refunded.getStatus())) {
            return ResponseFormat.fail("操作失败,当前订单状态:" + order.getStatus());
        }
        if (!order.getStatus().equals(BuyOrderStatus.admin.getStatus())) {
            return ResponseFormat.fail("操作失败,当前订单状态:" + order.getStatus() + ",未到当前流程");
        }
        order.setStatus(BuyOrderStatus.complete.getStatus());
        this.buyOrderService.updateById(order);
        Integer deviceId = order.getDeviceId();
        UpdateWrapper<BuyOzoneDevice> u1 = new UpdateWrapper<>();
        u1.set("can_use", true);
        u1.eq("id", deviceId);
        this.buyOzoneDeviceService.update(u1);
        return ResponseFormat.success();
    }

    private ResponseFormat validDevice(BuyOrder order, BuyOzoneDevice ozoneDevice) {
        Integer userId = MySecurity.getUserId();
        if (!order.getAdminUserId().equals(userId)) {
            return ResponseFormat.fail("不可操作他人订单");
        }
        if (order.getStatus().equals(BuyOrderStatus.complete.getStatus()) || order.getStatus().equals(BuyOrderStatus.refunded.getStatus())) {
            return ResponseFormat.fail("当前订单状态:" + order.getStatus() + ",操作失败");
        }
        if (ozoneDevice == null) {
            return ResponseFormat.fail("臭氧机器不存在");
        }
        if (!ozoneDevice.getAdminUserId().equals(userId)) {
            return ResponseFormat.fail("请选择自己的臭氧机器");
        }
        if (ozoneDevice.getClientUserId() != null) {
            return ResponseFormat.fail("当前臭氧机已经被其他客户绑定了");
        }
        //一定是绑定的
        if (ozoneDevice.getOxygenId() == null) {
            return ResponseFormat.fail("当前臭氧机未绑定氧气机");
        }
        UpdateWrapper<BuyOzoneDevice> u1 = new UpdateWrapper<>();
        u1.set("client_user_id", order.getClientUserId());
        u1.eq("id", ozoneDevice.getId());
        this.buyOzoneDeviceService.update(u1);
        UpdateWrapper<BuyOxygenDevice> u2 = new UpdateWrapper<>();
        u2.set("client_user_id", order.getClientUserId());
        u2.eq("id", ozoneDevice.getOxygenId());
        this.buyOxygenDeviceService.update(u2);
        return ResponseFormat.success();
    }

}
